﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using Revis.VClinicNet.Util.Extensions;

namespace Revis.VClinicNet.UI.External.Client.Service
{
    public class FakePatientService : IPatientService
    {
        private Random r = new Random();

        #region Login

        public void Login()
        {
        }

        public IAsyncResult BeginLogin(AsyncCallback callback, object asyncState)
        {
            Action action = () => Login();
            return action.BeginInvoke(callback, asyncState);
        }

        public void EndLogin(IAsyncResult result)
        {
            Action action = (Action)((AsyncResult)result).AsyncDelegate;
            action.EndInvoke(result);
        }

        #endregion

        #region Logout

        public void Logout()
        {
        }

        public IAsyncResult BeginLogout(AsyncCallback callback, object asyncState)
        {
            Action action = () => Logout();
            return action.BeginInvoke(callback, asyncState);
        }

        public void EndLogout(IAsyncResult result)
        {
            Action action = (Action)((AsyncResult)result).AsyncDelegate;
            action.EndInvoke(result);
        }

        #endregion


        #region PatientVisits

        public VisitDto[] Visits()
        {
            return new VisitDto[] {
                new VisitDto() { 
                    Date = DateTime.Now.AddDays(r.Integer(1,10)).AddHours(r.Integer(1,5)).AddMinutes(r.Integer(1,50)),
                    DoctorName = r.String(10),
                    Id = 1,
                    Room = r.String(5)                    
                },
                new VisitDto() { 
                    Date = DateTime.Now.AddDays(r.Integer(1,10)).AddHours(r.Integer(1,5)).AddMinutes(r.Integer(1,50)),
                    DoctorName = r.String(10),
                    Id = 2,
                    Room = r.String(5)
                },
                new VisitDto() { 
                    Date = DateTime.Now.AddDays(r.Integer(1,10)).AddHours(r.Integer(1,5)).AddMinutes(r.Integer(1,50)),
                    DoctorName = r.String(10),
                    Id = 3,
                    Room = r.String(5)
                },
                new VisitDto() { 
                    Date = DateTime.Now.AddDays(r.Integer(1,10)).AddHours(r.Integer(1,5)).AddMinutes(r.Integer(1,50)),
                    DoctorName = r.String(10),
                    Id = 4,
                    Room = r.String(5)
                }
            };
        }

        public IAsyncResult BeginVisits(AsyncCallback callback, object asyncState)
        {
            Func<VisitDto[]> func = () => Visits();
            return func.BeginInvoke(callback, asyncState);
        }

        public VisitDto[] EndVisits(IAsyncResult result)
        {
            Func<VisitDto[]> func = (Func<VisitDto[]>)((AsyncResult)result).AsyncDelegate;
            return func.EndInvoke(result);
        }

        #endregion

        #region PatientInfo

        public PatientDto Profile()
        {
            return new PatientDto() {
                Id = 1,
                Personal = new PersonalDataDto() {
                    Address = new AddressDto() {
                        City = r.String(10),
                        HomeNumber = r.String(10),
                        Municipality = r.String(10),
                        PostalCode = "23-123",
                        StreetName = r.String(10),
                        Telephone = r.NumberString(8)
                    },
                    FirstName = r.String(5),
                    Pesel = r.NumberString(11),
                    Surname = r.String(10)
                }
            };
        }

        public IAsyncResult BeginProfile(AsyncCallback callback, object asyncState)
        {
            Func<PatientDto> func = () => Profile();
            return func.BeginInvoke(callback, asyncState);
        }

        public PatientDto EndProfile(IAsyncResult result)
        {
            Func<PatientDto> func = (Func<PatientDto>)((AsyncResult)result).AsyncDelegate;
            return func.EndInvoke(result);
        }

        #endregion

        #region Doctors

        public DoctorDto[] Doctors()
        {
            return new DoctorDto[] {
                new DoctorDto() {
                    Id=0,
                    Name=r.String(10),                    
                    WorkTimes = RandWorkTime()
                },
                new DoctorDto() {
                    Id=0,
                    Name=r.String(10),                    
                    WorkTimes = RandWorkTime()
                },
                new DoctorDto() {
                    Id=0,
                    Name=r.String(10),                    
                    WorkTimes = RandWorkTime()
                },                
            };
        }

        private WorkTimeDto[] RandWorkTime()
        {
            return new WorkTimeDto[] { 
                    new WorkTimeDto() {                         
                        BeginInfo = r.String(7),
                        Day = DayOfWeek.Monday,
                        EndInfo = r.String(7),
                        Room = r.String(5)
                    },
                    new WorkTimeDto() { 
                        BeginInfo = r.String(7),
                        Day = DayOfWeek.Tuesday,
                        EndInfo = r.String(7),
                        Room = r.String(5)
                    },
                    new WorkTimeDto() { 
                        BeginInfo = r.String(7),
                        Day = DayOfWeek.Wednesday,
                        EndInfo = r.String(7),
                        Room = r.String(5)
                    },
                    new WorkTimeDto() { 
                        BeginInfo = r.String(7),
                        Day = DayOfWeek.Thursday,
                        EndInfo = r.String(7),
                        Room = r.String(5)
                    },                    
                };
        }


        public IAsyncResult BeginDoctors(AsyncCallback callback, object asyncState)
        {
            Func<DoctorDto[]> func = () => Doctors();
            return func.BeginInvoke(callback, asyncState);
        }

        public DoctorDto[] EndDoctors(IAsyncResult result)
        {
            Func<DoctorDto[]> func = (Func<DoctorDto[]>)((AsyncResult)result).AsyncDelegate;
            return func.EndInvoke(result);
        }

        #endregion

        #region Card

        public EntryDto[] Card()
        {
            return new EntryDto[] {
                new EntryDto() {
                    Author = r.String(10),
                    Date = DateTime.Now.AddDays(-r.Integer(1,10)).AddHours(-r.Integer(1,5)).AddMinutes(-r.Integer(1,50)),
                    Description = r.String(1000),
                    Id = 0,
                    Reason = r.String(10),
                    Recommendation = r.String(20)
                },
                new EntryDto() {
                    Author = r.String(10),
                    Date = DateTime.Now.AddDays(-r.Integer(1,10)).AddHours(-r.Integer(1,5)).AddMinutes(-r.Integer(1,50)),
                    Description = r.String(30),
                    Id = 0,
                    Reason = r.String(10),
                    Recommendation = r.String(20)
                },
                new EntryDto() {
                    Author = r.String(10),
                    Date = DateTime.Now.AddDays(-r.Integer(1,10)).AddHours(-r.Integer(1,5)).AddMinutes(-r.Integer(1,50)),
                    Description = r.String(30),
                    Id = 0,
                    Reason = r.String(10),
                    Recommendation = r.String(20)
                },
            };
        }

        public IAsyncResult BeginCard(AsyncCallback callback, object asyncState)
        {
            Func<EntryDto[]> func = () => Card();
            return func.BeginInvoke(callback, asyncState);
        }

        public EntryDto[] EndCard(IAsyncResult result)
        {
            Func<EntryDto[]> func = (Func<EntryDto[]>)((AsyncResult)result).AsyncDelegate;
            return func.EndInvoke(result);
        }

        #endregion

        #region ChangePassword

        public bool ChangePassword(string oldPassword, string newPassword)
        {
            return r.Integer(0, 10) < 5 ? true : false;
        }

        public IAsyncResult BeginChangePassword(string oldPassword, string newPassword, AsyncCallback callback, object asyncState)
        {
            Func<bool> func = () => ChangePassword(string.Empty, string.Empty);
            return func.BeginInvoke(callback, asyncState);
        }

        public bool EndChangePassword(IAsyncResult result)
        {
            Func<bool> func = (Func<bool>)((AsyncResult)result).AsyncDelegate;
            return func.EndInvoke(result);
        }

        #endregion

        #region Credentials

        public class ClientCredentialsImpl
        {
            public class UserNameImpl
            {
                public string UserName { get; set; }
                public string Password { get; set; }
            }

            public UserNameImpl UserName = new UserNameImpl();
        }

        public ClientCredentialsImpl ClientCredentials = new ClientCredentialsImpl();

        #endregion
    }
}
